home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / shells / cshel510 / part06 < prev   
Encoding:
Internet Message Format  |  1991-04-16  |  39.8 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i093: CShell 5.10 - alternative command interface, Part06/06
  4. Reply-To: umueller@iiic.ethz.ch
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v91i093@ab20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v91i088@ab20.larc.nasa.gov>
  8. Date: 16 Apr 91 19:34:38 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga.misc
  12.  
  13. Submitted-by: umueller@iiic.ethz.ch
  14. Posting-number: Volume 91, Issue 093
  15. Archive-name: shells/cshell-5.10/part06
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 6 (of 6)."
  24. # Contents:  execom.c
  25. # Wrapped by tadguy@ab20 on Tue Apr 16 15:34:35 1991
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'execom.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'execom.c'\"
  29. else
  30. echo shar: Extracting \"'execom.c'\" \(37168 characters\)
  31. sed "s/^X//" >'execom.c' <<'END_OF_FILE'
  32. X/*
  33. X * EXECOM.C
  34. X *
  35. X * Matthew Dillon, 10 August 1986
  36. X * Version 2.07M by Steve Drew 10-Sep-87
  37. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  38. X * Version 5.00L by Urban Mueller 17-Feb-91
  39. X *
  40. X */
  41. X
  42. X#include "shell.h"
  43. X
  44. X#define DEFAULTFRAME 1024
  45. X
  46. X
  47. Xtypedef struct StackFrame {
  48. X    struct StackFrame *next;
  49. X    int  bytesleft;
  50. X    char *ptr;
  51. X    char mem[1];
  52. X} FRAME;
  53. X
  54. X/* execom.c */
  55. Xstatic char *compile_avf(FRAME **frame,char **av,int start,int end,char delim,int quote);
  56. Xstatic int   hasspace( char *s );
  57. Xstatic void  preformat(char *s, char *d);
  58. Xstatic void  backtrans(char *str);
  59. Xstatic int   fcomm(char *str,FRAME **frame,char *from);
  60. Xstatic char *exarg(char **ptr, char *elast);
  61. Xstatic char *format_insert_string(FRAME **frameptr, char *str, char *from);
  62. Xstatic int   find_command(char *str);
  63. Xstatic void  exec_every(void);
  64. Xstatic void  show_usage(char *str);
  65. Xstatic void  get_opt(char **av, int *ac, int ccno);
  66. Xstatic int   checkav( FRAME **frame,int n );
  67. Xstatic char *tempname( int which );
  68. Xstatic char *skipword( char *strskip );
  69. Xstatic int   myfgets( char *buf, FILE *in );
  70. X
  71. Xstatic void  newframe( FRAME **frame, int bytes);
  72. Xstatic char  *falloc( FRAME **frame, int bytes );
  73. Xstatic char  *frealloc( FRAME **frame, char *oldstring, int morebytes );
  74. Xstatic void  funalloc( FRAME **frame, int bytes );
  75. Xstatic char  *push_cpy( FRAME **frame, char *s);
  76. Xstatic void  deleteframe( FRAME *frame);
  77. X
  78. Xint do_nothing(void);
  79. X
  80. Xstruct COMMAND {
  81. X    int (*func)();
  82. X    short minargs;
  83. X    short stat;
  84. X    int val;
  85. X    char *name;
  86. X    char *options;
  87. X    char *usage;
  88. X};
  89. X
  90. X#define ST_COND   0x01
  91. X#define ST_NORED  0x02
  92. X#define ST_NOEXP  0x04
  93. X#define ST_AV     0x08 /* delimit args within a variable */
  94. X#define ST_FUNC   0x10
  95. X#define ST_EQUAL  0x20
  96. X
  97. X#define COND  ST_COND
  98. X#define NORED ST_NORED
  99. X#define NOEXP ST_NOEXP
  100. X#define AV    ST_AV
  101. X#define FUNC  ST_FUNC
  102. X#define EQUAL ST_EQUAL
  103. X
  104. X#define ALIAS LEVEL_ALIAS
  105. X#define SET   LEVEL_SET
  106. X#define LOCAL LEVEL_LOCAL
  107. X
  108. Xstruct COMMAND Command[] = {
  109. X do_run,       0,   AV,     0, "\001",       NULL, NULL, /* may call do_source, do_cd */
  110. X do_nothing,   0,    0,     0, "\002",       NULL, NULL, /* dummy for aliases   */
  111. X do_nothing,   0,    0,     0, "\003",       NULL, NULL, /* dummy for aliases with args */
  112. X do_abortline, 0,    0,     0, "abortline",  NULL, "",
  113. X do_action,    2,    0,     9, "action",     "av", "action file [args]",
  114. X do_addbuffers,2,    0,     0, "addbuffers", NULL, "{drive bufs}",
  115. X do_set_var,   0,    0, ALIAS, "alias",      NULL, "[name [string] ]",/* uses avline */
  116. X do_ascii,     0,    0,     0, "ascii",      "oh", "-oh [string]",
  117. X do_aset,      1,    0,     0, "aset",       NULL, "name value",
  118. X do_assign,    0,    0,     0, "assign",     "lnp",",logical,-lnp {logical physical}",
  119. X do_basename,  2, FUNC,     0, "basename",   NULL, "var path",
  120. X do_cat,       0,    0,     0, "cat",        "n",  "-n [file file...]",
  121. X do_cd,        0,    0,     0, "cd",         "g",  "[path],-g path...path",
  122. X do_class,     0,   AV,     0, "class",      "n",  "-n name {type=param} \"actions\" {action=command}",
  123. X do_close,     0,    0,     0, "close",      NULL, "filenumber",
  124. X do_copy,      1,    0,     0, "copy",       "rudpfm","-dfmpru file file,-ud file...file dir,-ud dir...dir dir",
  125. X do_copy,      1,    0,     0, "cp",         "rudpfm","-dfmpru file file,-ud file...file dir,-ud dir...dir dir",
  126. X do_date,      0,    0,     0, "date",       "sr", "-sr [date/time]",
  127. X do_inc,       1,    0,    -1, "dec",        NULL, "varname [step]",
  128. X do_rm,        0,    0,     0, "delete",     "rp", "-pr file...file",
  129. X do_dir,       0,NOEXP,     0, "dir",        "sfdcnhltbuikqavopzeg","-abcdefghiklnopqstuv [-z lformat] [path...path]",
  130. X do_diskchange,1,    0,     0, "diskchange", NULL, "drive",
  131. X do_echo,      0,   AV,     0, "echo",       "ne", "-ne string",
  132. X do_if,        0, COND,     1, "else",       NULL, "",
  133. X do_if,        0, COND,     2, "endif",      NULL, "",
  134. X do_error,     1,    0,     0, "error",      NULL, "num",
  135. X do_exec,      1,    0,     0, "exec",       NULL, "command",
  136. X do_fault,     1,    0,     0, "fault",      NULL, "error",
  137. X do_filenote,  1,    0,     0, "filenote",   "s",  "file...file note,-s file...file",
  138. X do_fileslist, 0,    0,     0, "flist",      NULL, "",
  139. X do_fltlower,  0,    0,     0, "fltlower",   NULL, "<in >out",
  140. X do_fltupper,  0,    0,     0, "fltupper",   NULL, "<in >out",
  141. X do_foreach,   3,    0,     0, "foreach",    "v",  "-v varname ( string ) command",
  142. X do_forever,   1,    0,     0, "forever",    NULL, "command",
  143. X do_forline,   3,    0,     0, "forline",    NULL, "var filename command",
  144. X do_fornum,    4,    0,     0, "fornum",     "vs", "-vs var n1 n2 command",
  145. X do_getenv,    1, FUNC,     0, "getenv",     NULL, "shellvar envvar",
  146. X do_goto,      1,    0,     0, "goto",       NULL, "label",
  147. X do_head,      1,    0,     0, "head",       NULL, "filename [num]",
  148. X do_help,      0,    0,     0, "help",       NULL, "",
  149. X do_history,   0,    0,     0, "history",    NULL, "[partial_string]",
  150. X do_howmany,   0,    0,     0, "howmany",    NULL, "",
  151. X do_htype,     1,    0,     0, "htype",      "r",  "-r file...file",
  152. X do_if,        1,COND|NORED,0, "if",         "rftmdvn","-n arg cond arg,-n arg,-nf file,-nd dir -nm,-nt file...file,-nr rpn_expr,-v varname",
  153. X do_inc,       1,    0,     1, "inc",        NULL, "varname [step]",
  154. X do_info,      0,    0,     0, "info",       NULL, "[drive...drive]",
  155. X do_input,     1,    0,     0, "input",      "sr", "-rs var...var",
  156. X do_join,      2,    0,     1, "join",       "r",  "-r file...file",
  157. X do_keymap,    1,    0,     0, "keymap",     "n",  "-n number {key=function}",
  158. X do_label,     1, COND,     0, "label",      NULL, "name",
  159. X do_local,     0,    0,     0, "local",      NULL, "[var...var]",
  160. X do_linecnt,   0,    0,     0, "linecnt",    NULL, "<in >out",
  161. X do_dir,       0,NOEXP,     0, "ls",         "sfdcnhltbuikqavopzeg","-abcdefghiklnopqstuv [-z format] [path...path]",
  162. X do_man,       0,    0,     0, "man",        NULL, "command...command",
  163. X do_mkdir,     0,    0,     0, "md",         NULL, "name...name",
  164. X do_mem,       0,    0,     0, "mem",        "cfqsr","-cfqsr",
  165. X do_menu,      0,    0,     0, "menu",       "n",  "-n [title item...item]",
  166. X do_mkdir,     0,    0,     0, "mkdir",      NULL, "name...name",
  167. X do_mv,        2,    0,     0, "mv",         NULL, "from to,from...from todir",
  168. X do_open,      3,    0,     0, "open",       NULL, "file mode number",
  169. X do_path,      0,    0,     0, "path",       "r",  "-r [dir...dir]",
  170. X do_pri,       2,    0,     0, "pri",        NULL, "clinumber pri,0 pri",
  171. X do_protect,   2,    0,     0, "protect",    NULL, "file...file flags",
  172. X do_ps,        0,    0,     0, "ps",         "le", "-el [commandname...commandname]",
  173. X do_pwd,       0,    0,     0, "pwd",        NULL, "",
  174. X do_qsort,     0,    0,     0, "qsort",      "r",  "-r <in >out",
  175. X do_quit,      0,NORED,     0, "quit",       NULL, "",
  176. X do_truerun,   1,NORED,     1, "rback",      NULL, "command",
  177. X do_mv,        2,    0,     0, "rename",     NULL, "from to,from...from todir",
  178. X do_readfile,  1,    0,     0, "readfile",   NULL, "varname [filename]",
  179. X do_relabel,   2,    0,     0, "relabel",    NULL, "drive name",
  180. X do_resident,  0,    0,     0, "resident",   "ard",",-ard file...file",
  181. X do_return,    0,    0,     0, "return",     NULL, "[n]",
  182. X do_rm,        0,    0,     0, "rm",         "rp", "-rp file...file",
  183. X do_rpn,       0,NOEXP,     0, "rpn",        NULL, "expression",
  184. X do_rxrec,     0,    0,     0, "rxrec",      NULL, "[portname]",
  185. X do_rxsend,    2,    0,     0, "rxsend",     "rl", "-lc portname string",
  186. X do_truerun,   1,NORED,     0, "run",        NULL, "command",
  187. X do_search,    2,    0,     0, "search",     "rcwneqvbfalo","-abceflnoqrvw file...file string",
  188. X do_set_var,   0,   AV,   SET, "set",        NULL, "[name [string] ]",
  189. X do_setenv,    2,    0,     0, "setenv",     NULL, "var value",
  190. X do_sleep,     0,    0,     0, "sleep",      NULL, "timeout",
  191. X do_split,     1,    0,     0, "split",      NULL, "srcvar dstvar...dstvar",
  192. X do_source,    1,   AV,     0, "source",     NULL, "file", /* uses avline */
  193. X do_stack,     0,    0,     0, "stack",      NULL, "[bytes]",
  194. X do_strhead,   3, FUNC,     0, "strhead",    NULL, "varname breakchar string",
  195. X do_strings,   1,    0,     0, "strings",    "r",  "-r file...file minlength",
  196. X do_strleft,   3, FUNC,     0, "strleft",    NULL, "varname string n",
  197. X do_strlen,    2, FUNC,     0, "strlen",     NULL, "varname string",
  198. X do_strmid,    3, FUNC,     0, "strmid",     NULL, "varname string n1 [n2]",
  199. X do_strright,  3, FUNC,     0, "strright",   NULL, "varname string n",
  200. X do_strtail,   3, FUNC,     0, "strtail",    NULL, "varname breakchar string",
  201. X do_tackon,    3, FUNC,     0, "tackon",     NULL, "var pathname filename",
  202. X do_head,      1,    0,     1, "tail",       NULL, "filename [num]",
  203. X do_tee,       0,    0,     0, "tee",        NULL, "<in >out",
  204. X do_touch,     0,    0,     0, "touch",      NULL, "file...file",
  205. X do_truncate,  0,    0,     0, "truncate",   NULL, "<in >out",
  206. X do_cat,       0,    0,     0, "type",       NULL, "-n [file...file]",
  207. X do_unset_var, 0,    0, ALIAS, "unalias",    NULL, "name...name",
  208. X do_uniq,      0,    0,     0, "uniq",       NULL, "<in >out",
  209. X do_unset_var, 0,    0, LOCAL, "unlocal",    NULL, "var...var",
  210. X do_unset_var, 0,    0,   SET, "unset",      NULL, "name...name",
  211. X do_usage,     0,    0,     0, "usage",      NULL, "[command...command]",
  212. X do_ver,       0,    0,     0, "version",    NULL, "",
  213. X do_waitport,  1,    0,     0, "waitforport",NULL, "portname [seconds]",
  214. X do_whereis,   1,NOEXP,     0, "whereis",    "r",  "-r file [path...path]",
  215. X do_window,    0,NOEXP,     0, "window",     "slfbaq","-slfbaq",
  216. X NULL,         0,    0,     0, NULL,         NULL, NULL,
  217. X};
  218. X
  219. X
  220. X/* do_which,     1,    0,     0, "which",      NULL, "command", */
  221. X
  222. X#ifdef isalphanum
  223. Xchar isalph[256];
  224. X#endif
  225. X
  226. Xint
  227. Xexec_command( char *base )
  228. X{
  229. X    FRAME *frame=NULL;
  230. X    char *scr, buf[6];
  231. X    int  len, ret;
  232. X
  233. X    if (!H_stack && S_histlen>1) {
  234. X        add_history(base);
  235. X        sprintf(buf, "%d", H_tail_base + H_len);
  236. X        set_var(LEVEL_SET, v_histnum, buf);
  237. X    }
  238. X
  239. X    len=strlen(base)*3+20;
  240. X    newframe( &frame, len+DEFAULTFRAME );
  241. X
  242. X    scr = falloc(&frame,len);
  243. X    preformat( base,scr );
  244. X
  245. X    funalloc( &frame, len-strlen(scr)-2 );
  246. X    ret=fcomm(scr,&frame,NULL);
  247. X
  248. X    deleteframe( frame );
  249. X
  250. X    return ret;
  251. X}
  252. X
  253. X#ifndef isalphanum
  254. Xisalphanum( char c )
  255. X{
  256. X    return (
  257. X        (c >= 'a' && c <= 'z') ||
  258. X        (c >= 'A' && c <= 'Z') ||
  259. X        (c >= '0' && c <= '9') ||
  260. X        (c == '_')
  261. X    );
  262. X}
  263. X#endif
  264. X
  265. X#define HOT_GAP    0x80
  266. X#define HOT_BLANK  0x81
  267. X#define HOT_STAR   0x82
  268. X#define HOT_QUES   0x83
  269. X#define HOT_EXCL   0x84
  270. X#define HOT_SEMI   0x85
  271. X#define HOT_PIPE   0x86
  272. X#define HOT_DOLLAR 0x87
  273. X#define HOT_IN     0x88
  274. X#define HOT_OUT    0x89
  275. X#define HOT_BSLASH 0x8a
  276. X#define HOT_LASTCD 0x8b
  277. X#define HOT_BACKG  0x8c
  278. X#define HOT_CURLL  0x8d
  279. X#define HOT_CURLR  0x8e
  280. X#define HOT_CURDIR 0x8f
  281. X#define HOT_PARDIR 0x90
  282. X#define HOT_BEGOUT 0x91
  283. X#define HOT_ENDOUT 0x92
  284. X#define HOT_EQUAL  0x93
  285. X#define HOT_BEGIN  0x94
  286. X#define HOT_APOSTR 0x95
  287. X
  288. X
  289. X
  290. X
  291. Xvoid
  292. Xpreformat( char *s, char *d )
  293. X{
  294. X    static char termchar[]={ 0,    '}',       ')',        '`' };
  295. X    static char hotchar []={ 0, HOT_CURLR, HOT_ENDOUT, HOT_APOSTR };
  296. X    int qm=0, i, level, curmode, argc=0, beg=1;
  297. X    char mode[100], c;
  298. X
  299. X    while (*s) {
  300. X        if (qm ) {
  301. X            while( *s && *s != '\"' && *s != '\\')
  302. X                *d++ = *s++;
  303. X            if( !*s ) break;
  304. X        }
  305. X        if( beg ) c=HOT_BEGIN,beg=0; else c=*s;
  306. X        switch (c) {
  307. X        case ' ':
  308. X        case 9:
  309. X            *d++ = HOT_BLANK;
  310. Xargstart:
  311. X            while (*s == ' ' || *s == 9) ++s;
  312. X            if( *s == '\\' && !argc )    { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; }
  313. X            if( *s == '~'  )             { *d++=HOT_LASTCD; s++; }
  314. X            else if( *s=='.'&&s[1]=='.') { *d++=HOT_PARDIR; *d++='.'; s+=2; }
  315. X            else if( *s=='.' )           { *d++=HOT_CURDIR; s++; }
  316. X            else if( argc && (!*s || *s == '|' || *s == ';' || *s=='#')) --d;
  317. X            argc++;
  318. X            break;
  319. X        case '*':
  320. X            *d++ = HOT_GAP;
  321. X            *d++ = HOT_STAR;
  322. X            ++s;
  323. X            break;
  324. X        case '?':
  325. X            *d++ = HOT_GAP;
  326. X            *d++ = HOT_QUES;
  327. X            ++s;
  328. X            break;
  329. X        case '!':
  330. X            *d++ = HOT_EXCL;
  331. X            ++s;
  332. X            break;
  333. X        case '#':
  334. X            *d++ = '\0';
  335. X            while (*s) ++s;
  336. X            break;
  337. X        case HOT_BEGIN:
  338. X            argc=0;
  339. X            goto argstart;
  340. X        case ';':
  341. X            *d++= HOT_SEMI, argc=0, s++;
  342. X            goto argstart;
  343. X        case '|':
  344. X            *d++= HOT_PIPE, argc=0, s++;
  345. X            goto argstart;
  346. X        case '\\':
  347. X            if( (i=*++s-'0')>=0 && i<=7 ) {
  348. X                if( *++s>='0' && *s<='7' ) {
  349. X                    i= 8*i + *s++-'0';
  350. X                    if( *s>='0' && *s<='7' )
  351. X                        i= 8*i + *s++-'0';
  352. X                }
  353. X                *d++ = i;
  354. X            } else {
  355. X                *d++ = *s;
  356. X                if (*s) ++s;
  357. X            }
  358. X            break;
  359. X        case '\"':
  360. X            qm = 1 - qm;
  361. X            ++s;
  362. X            break;
  363. X        case '^':
  364. X            *d++ = *++s & 0x1F;
  365. X            if (*s) ++s;
  366. X            break;
  367. X        case '<':
  368. X            *d++ = HOT_IN;
  369. X            ++s;
  370. X            break;
  371. X        case '>':
  372. X            *d++ = HOT_OUT;
  373. X            ++s;
  374. X            break;
  375. X        case '&':
  376. X            *d++ = HOT_BACKG;
  377. X            ++s;
  378. X            break;
  379. X        case '$': /* search end of var name */
  380. X            if( s[1]=='(' ) {
  381. X                curmode=2;
  382. X                *d++=HOT_BEGOUT;
  383. X                *d++=*++s;
  384. X                goto brace;
  385. X            }
  386. X            *d++ = HOT_GAP;
  387. X            *d++ = HOT_DOLLAR;
  388. X            ++s;
  389. X            while (isalphanum(*s)) *d++ = *s++;
  390. X            *d++ = HOT_GAP;
  391. X            break;
  392. X        case '`':
  393. X            curmode=3;
  394. X            *d++=HOT_APOSTR;
  395. X            goto brace;
  396. X        case '{':
  397. X            curmode=1;
  398. X            *d++ = HOT_CURLL;
  399. Xbrace:
  400. X            level=0; s++;
  401. X            mode[level++]=curmode;
  402. X            while( *s && level ) {
  403. X                switch( *s ) {
  404. X                case '\"': *d++=*s++;
  405. X                           while( *s && *s!='\"' )
  406. X                               if( *s=='\\' ) { *d++=*s++; if( *s ) *d++=*s++; }
  407. X                               else *d++=*s++;
  408. X                           if( *s ) *d++=*s++;
  409. X                           break;
  410. X                case '\\': *d++=*s++; if( *s ) *d++=*s++;
  411. X                           break;
  412. X                case '{' : mode[level++]=1; s++;
  413. X                           break;
  414. X                case '}' :
  415. X                case ')' :
  416. X                case '`' : for( i=level-1; i>=0 && termchar[mode[i]]!=*s;--i ) ;
  417. X                           if( i==0 ) *d++=hotchar [mode[i]];
  418. X                           if( i>=0 ) level=i;
  419. X                           s++;
  420. X                           break;
  421. X                default  : *d++=*s++;
  422. X                           break;
  423. X                }
  424. X            }
  425. X            break;
  426. X        default:
  427. X            *d++ = *s++;
  428. X            while( *s>=65 && (*s&31)<=26 )
  429. X                *d++=*s++;
  430. X            break;
  431. X        }
  432. X    }
  433. X    *d++=0;
  434. X    *d=0;
  435. X    if (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
  436. X    return;
  437. X}
  438. X
  439. Xstatic void
  440. Xbacktrans( char *str )
  441. X{
  442. X    while( *str ) {
  443. X        while( *(signed char *)str>0 ) str++;
  444. X        if( !*str ) break;
  445. X        switch( *str) {
  446. X            case HOT_GAP   : *str++=0;    break;
  447. X            case HOT_BLANK : *str++=' ';  break;
  448. X            case HOT_STAR  : *str++='*';  break;
  449. X            case HOT_QUES  : *str++='?';  break;
  450. X            case HOT_EXCL  : *str++='!';  break;
  451. X            case HOT_SEMI  : *str++=';';  break;
  452. X            case HOT_PIPE  : *str++='|';  break;
  453. X            case HOT_DOLLAR: *str++='$';  break;
  454. X            case HOT_IN    : *str++='<';  break;
  455. X            case HOT_OUT   : *str++='>';  break;
  456. X            case HOT_BSLASH: *str++='\\'; break;
  457. X            case HOT_LASTCD: *str++='~';  break;
  458. X            case HOT_BACKG : *str++='&';  break;
  459. X            case HOT_CURLL : *str++='{';  break;
  460. X            case HOT_CURLR : *str++='}';  break;
  461. X            case HOT_CURDIR: *str++='.';  break;
  462. X            case HOT_PARDIR: *str++='.';  break;
  463. X            case HOT_BEGOUT: *str++='$';  break;
  464. X            case HOT_ENDOUT: *str++=')';  break;
  465. X            case HOT_EQUAL : *str++='=';  break;
  466. X            case HOT_APOSTR: *str++='`';  break;
  467. X            default        : str++;       break;
  468. X        }
  469. X    }
  470. X}
  471. X
  472. X/*
  473. X * process formatted string.  ' ' is the delimeter.
  474. X *
  475. X *    0: check '\0': no more, stop, done.
  476. X *    1: check $.     if so, extract, format, insert
  477. X *    2: check alias. if so, extract, format, insert. goto 1
  478. X *    3: check history or substitution, extract, format, insert. goto 1
  479. X *
  480. X *    4: assume first element now internal or disk based command.
  481. X *
  482. X *    5: extract each ' ' or 0x80 delimited argument and process, placing
  483. X *       in av[] list (except 0x80 args appended).  check in order:
  484. X *
  485. X *             '$'         insert string straight
  486. X *             '>'         setup stdout
  487. X *             '>>'        setup stdout flag for append
  488. X *             '<'         setup stdin
  489. X *             '*' or '?'  do directory search and insert as separate args.
  490. X *
  491. X *             ';' 0 '|'   end of command.  if '|' setup stdout
  492. X *                          -execute command, fix stdin and out (|) sets
  493. X *                           up stdin for next guy.
  494. X */
  495. X
  496. Xint  alias_count;
  497. Xint  has_wild;                 /* set if any arg has wild card */
  498. Xchar *LastCommand;
  499. XBPTR OldCin;
  500. X
  501. X#define MAXACDEF 32
  502. X
  503. Xint
  504. Xfcomm( char *str, FRAME **frameptr, char *from )
  505. X{
  506. X    char *nextstr, *command;
  507. X    char *pend_alias;
  508. X    char cout_ispipe=0, cin_ispipe=0, cout_append=0, elast;
  509. X    char backg, firstrun, override, block;
  510. X    char *cin_name=NULL, *cout_name=NULL;
  511. X    char **oldav=av;
  512. X    int  oldac=ac, oldmax=max_ac, err, ccno, cstat;
  513. X
  514. X    max_ac= MAXACDEF;
  515. X    av=(char **)falloc( frameptr, max_ac*sizeof(char *));
  516. X    ac=0;
  517. X
  518. X    if (++alias_count >= MAXALIAS) {           /* Recursion getting too deep? */
  519. X        fprintf(stderr,"Alias Loop\n");
  520. X        err = 20;
  521. X        goto done1;
  522. X    }
  523. X
  524. Xnextcommand:
  525. X    command   = NULL;
  526. X    pend_alias= NULL;
  527. X    err       = 0;
  528. X    has_wild  = 0;
  529. X    firstrun  = 1;
  530. X    ccno=cstat= 0;
  531. X    elast     = 1;
  532. X    block     = 0;
  533. X
  534. X    if (*str == 0)
  535. X        goto done1;
  536. X
  537. X    if (*str == HOT_EXCL) {
  538. X        char *p, c, *istr;                       /* fix to allow !cmd1;!cmd2 */
  539. X        for(p = str; *p && *p != HOT_SEMI ; ++p);
  540. X        c = *p;
  541. X        *p = 0;
  542. X        if( str[1]==HOT_EXCL ) str[1]='!';
  543. X        istr = get_history(str,1);
  544. X        *p = c;
  545. X        replace_head(istr);
  546. X        str = format_insert_string( frameptr, str, istr );
  547. X    }
  548. X
  549. X    /*******************************************************
  550. X     * Part one of the parser:
  551. X     * The argument line is generated as an array of strings
  552. X     */
  553. X
  554. X    nextstr = str;
  555. X    ac = 0;
  556. X    do {              /* outer loop: each pass typically generates one av[ac] */
  557. X        char *arg, *ptr;
  558. X        short redir;
  559. X        short doexpand;
  560. X        short cont;
  561. X        short inc;
  562. X
  563. X        av[ac] = NULL;
  564. X        cont = 1;
  565. X        doexpand = redir = inc = 0;
  566. X
  567. X        while (cont && elast) {       /* inner loop: adds one piece to av[ac] */
  568. X            ptr = exarg(&nextstr,&elast);
  569. X            inc = 1;
  570. X            cont = (elast == 0x80);
  571. X            switch (*ptr) {                  /* arg must be set in every case */
  572. X            case HOT_IN:
  573. X                redir = -2;
  574. X            case HOT_OUT:
  575. X                if (cstat & (ST_NORED | ST_COND)) {     /* don't extract   */
  576. X                    redir = 0;                          /* <> stuff if its */
  577. X                    arg = ptr;                          /* external cmd.   */
  578. X                    break;
  579. X                }
  580. X                ++redir;
  581. X                arg = ptr + 1;
  582. X                if (*arg == HOT_OUT) {
  583. X                    redir = 2;        /* append >> */
  584. X                    ++arg;
  585. X                }
  586. X                cont = 1;
  587. X                break;
  588. X            case HOT_DOLLAR:
  589. X                /* restore args if from set command or pend_alias */
  590. X                if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) {
  591. X                    char *pe, sv;
  592. X                    while (pe = index(arg,0xA0)) {
  593. X                        sv = *pe;
  594. X                        *pe = '\0';
  595. X                        checkav(frameptr,1);
  596. X
  597. X                        if (av[ac]) {
  598. X                            av[ac] = frealloc( frameptr,av[ac],strlen(arg));
  599. X                            strcat(av[ac++], arg);
  600. X                        } else
  601. X                            av[ac++] = push_cpy(frameptr,arg);
  602. X
  603. X                        *pe = sv;
  604. X                        av[ac] = NULL;
  605. X                        arg = pe+1;
  606. X                    }
  607. X                } else
  608. X                    arg = ptr;
  609. X                break;
  610. X            case HOT_LASTCD:
  611. X                if ((!ptr[1] || ptr[1]=='/')&&(arg=get_var(LEVEL_SET, v_lcd))) {
  612. X                    if( ptr[1] ) {
  613. X                        strcpy(Buf,arg);
  614. X                        strcat(Buf,ptr+1);
  615. X                        arg=Buf;
  616. X                    } 
  617. X                } else
  618. X                    arg = ptr;
  619. X                break;
  620. X            case HOT_CURDIR:
  621. X                arg=ptr;
  622. X                if( !ptr[1] || ptr[1]=='/' )
  623. X                    arg= ptr[1] ? ptr+2 : ptr+1;
  624. X                break;
  625. X            case HOT_PARDIR:
  626. X                arg=ptr;
  627. X                if( !ptr[2] || ptr[2]=='/' )
  628. X                    arg= ptr[2] ? ptr+2 : "/";
  629. X                break;
  630. X
  631. X            case HOT_STAR:
  632. X            case HOT_QUES:
  633. X                if( !(cstat & ST_NOEXP) && !(pend_alias && *pend_alias=='*'))
  634. X                    if( ac!=1 || av[1]&&*av[1] || *ptr!=HOT_QUES || ptr[1] )
  635. X                        doexpand = 1;
  636. X                arg = ptr;
  637. X                break;
  638. X            default:
  639. X                arg = ptr;
  640. X                break;
  641. X            }
  642. X
  643. X            /* Append arg to av[ac] */
  644. X
  645. X            if (av[ac]) {
  646. X                av[ac] = frealloc( frameptr,av[ac],strlen(arg));
  647. X                strcat(av[ac], arg);
  648. X            } else
  649. X                av[ac] = push_cpy(frameptr,arg);
  650. X
  651. X            if (elast != 0x80)
  652. X                break;
  653. X        }
  654. X
  655. X        /* one argument is now complete */
  656. X
  657. X        backg   = *av[ac] && av[ac][strlen(av[ac])-1]==HOT_BACKG;
  658. X        override= *av[ac] == HOT_BSLASH;
  659. X
  660. X        if( firstrun && *av[0] == HOT_CURLL ) {
  661. X            char *end;
  662. X            av[0]++;
  663. X            if( end=index(av[0],HOT_CURLR)) *end=0;
  664. X            block=1;
  665. X        }
  666. X
  667. X        if( *av[ac]==HOT_BEGOUT || *av[ac]==HOT_APOSTR ) {
  668. X            BPTR cout, oldcout= Myprocess->pr_COS;
  669. X            FILE *in;
  670. X            char *t, *val;
  671. X            int  apo;
  672. X
  673. X            apo= *av[ac]==HOT_APOSTR;
  674. X            inc=0;
  675. X            if( t=index(av[ac]+1, apo ? HOT_APOSTR : HOT_ENDOUT ))
  676. X                *t=0;
  677. X
  678. X            if(!(cout = Open(tempname(2),MODE_NEWFILE))) {
  679. X                err= 20;
  680. X                ierror (NULL, 504);
  681. X            } else {
  682. X                Myprocess->pr_COS = DEVTAB(stdout) = cout;
  683. X                execute(av[ac]+2-apo);
  684. X                Close(cout);
  685. X
  686. X                if(!(in=fopen(tempname(2),"r"))) {
  687. X                    err= 1;
  688. X                    ierror (NULL, 504);
  689. X                } else {
  690. X                    while( myfgets(Buf,in))
  691. X                        if( apo ) {
  692. X                            for( val=Buf; t=index(val,' '); val=t+1)
  693. X                                *t=0, av[ac++]=push_cpy(frameptr,val);
  694. X                            av[ac++]= push_cpy(frameptr,val);
  695. X                        } else 
  696. X                            av[ac++]= push_cpy(frameptr,Buf);
  697. X                    fclose(in);
  698. X                    DeleteFile(tempname(2));
  699. X                }
  700. X            }
  701. X
  702. X            Myprocess->pr_COS = DEVTAB(stdout) = oldcout;
  703. X        }
  704. X
  705. X        backtrans( av[ac] );
  706. X
  707. X        if (doexpand) {                                  /* process expansion */
  708. X            char **eav, **ebase;
  709. X            int eac;
  710. X            has_wild = 1;
  711. X            eav = ebase = expand(av[ac], &eac);
  712. X            inc = 0;
  713. X            if (eav) {
  714. X                if( checkav( frameptr, eac ) ) {
  715. X                    ierror (NULL, 506);
  716. X                    err = 1;
  717. X                } else {
  718. X                    QuickSort(eav, eac);
  719. X                    for (; eac; --eac, ++eav)
  720. X                        av[ac++] = push_cpy(frameptr,*eav);
  721. X                }
  722. X                free_expand (ebase);
  723. X            }
  724. X        } else if( av[ac][0]==')' ) {
  725. X            int i;
  726. X            char *pe, sv;
  727. X            for( i=ac-1; i>0; i-- )
  728. X                if( *av[i]=='@' )
  729. X                    break;
  730. X            if( i>0 && av[i][strlen(av[i])-1]=='(' ) {
  731. X                extern int exec_fn_err;
  732. X                char *exec_function();
  733. X                char *avi=av[i], *last=av[ac];
  734. X                av[i]=v_value; av[ac]=NULL;
  735. X                arg=exec_function( avi+1, av+i, ac-i );
  736. X                av[i]=avi;     av[ac]=last;
  737. X                inc=0;
  738. X                if( exec_fn_err<0 )
  739. X                    ac++;
  740. X                else if( exec_fn_err>0 || !arg )
  741. X                    ac=i, av[ac]=NULL;
  742. X                else {
  743. X                    ac=i;
  744. X                    while (pe = index(arg,0xA0)) {
  745. X                        sv = *pe;
  746. X                        *pe = '\0';
  747. X                        checkav( frameptr, 1 );
  748. X                        av[ac++] = push_cpy(frameptr,arg);
  749. X                        *pe = sv;
  750. X                        arg= pe+1;
  751. X                    }
  752. X                    av[ac] = falloc(frameptr,strlen(arg)+strlen(last+1)+4);
  753. X                    strcpy(av[ac],arg);
  754. X                    strcat(av[ac++], last+1 );
  755. X                }
  756. X            }
  757. X        }
  758. X
  759. X        /*******************************
  760. X         * special handling of first arg
  761. X         */
  762. X
  763. X        if( firstrun ) {                     /* we just found out the command */
  764. X            firstrun=0;
  765. X            command=av[0];
  766. X
  767. X            if (*command == 0)
  768. X                goto done0;
  769. X
  770. X            if( block )
  771. X                pend_alias=command;
  772. X            else if ( override )
  773. X                memmove( command, command+1, strlen(command));
  774. X            else {
  775. X                pend_alias=get_var(LEVEL_ALIAS,command);  /* if not \command */
  776. X                if( pend_alias && pend_alias==from )
  777. X                    pend_alias=NULL;
  778. X            }
  779. X
  780. X            if( pend_alias )
  781. X                ccno=*pend_alias=='%' || *pend_alias=='*' ? 2 : 1;
  782. X            else 
  783. X                ccno=find_command(command);
  784. X            cstat=Command[ccno].stat;
  785. X
  786. X            if ( !(cstat & ST_COND) && (disable || forward_goto) ) {
  787. X                while (elast && elast != HOT_SEMI && elast != HOT_PIPE)
  788. X                    exarg(&nextstr,&elast);
  789. X                goto done0;
  790. X            }
  791. X        }
  792. X
  793. X        if (redir && !err) {                            /* store redirection  */
  794. X            char *file = (doexpand) ? av[--ac] : av[ac];
  795. X
  796. X            if (redir < 0)
  797. X                cin_name = file;
  798. X            else {
  799. X                cout_name = file;
  800. X                cout_append = (redir == 2);
  801. X            }
  802. X            inc = 0;
  803. X        }
  804. X
  805. X        if (inc) {                                   /* check elast for space */
  806. X            ++ac;
  807. X            if( checkav(frameptr,1) ) {
  808. X                ierror (NULL, 506);
  809. X                err = 1;                                   /* error condition */
  810. X                elast = 0;                /* don't process any more arguemnts */
  811. X            }
  812. X        }
  813. X    } while( elast==HOT_BLANK );
  814. X    av[ac] = NULL;
  815. X
  816. X
  817. X    /******************************************************************
  818. X     * Part two:
  819. X     * The argument line is processed (pipes, commands, recursive calls
  820. X     */
  821. X
  822. X    /* process pipes via files */
  823. X
  824. X    if (elast == HOT_PIPE && !err) {
  825. X        static int which;             /* 0 or 1 in case of multiple pipes */
  826. X        which = 1 - which;
  827. X        cout_name = tempname( which );
  828. X        cout_ispipe = 1;
  829. X    }
  830. X
  831. X
  832. X    if (err)
  833. X        goto done0;
  834. X
  835. X    {
  836. X        char *avline;
  837. X        char delim = ' ';
  838. X        BPTR  oldcin  = Myprocess->pr_CIS, cin=NULL;
  839. X        BPTR  oldcout = Myprocess->pr_COS, cout=NULL;
  840. X        char *cin_buf=NULL;
  841. X        struct FileHandle *ci=NULL;
  842. X        long oldbuf=NULL;
  843. X
  844. X        if( backg ) {
  845. X            char *larg=av[ac-1];
  846. X            memmove( av+1, av, ac*sizeof(*av));
  847. X            command=av[0]="rback";
  848. X            ccno=find_command(command);
  849. X            cstat=Command[ccno].stat;
  850. X            if( strlen(larg)>1 )
  851. X                larg[strlen(larg)-1]=0, ac++;
  852. X        }
  853. X        if( ccno==2 || (cstat & ST_AV))            /* alias with argument */
  854. X            delim = 0xA0;
  855. X        avline = compile_avf(frameptr,av,(pend_alias?1:0), ac, delim, ccno==1);
  856. X
  857. X        OldCin=oldcin;
  858. X        fflush(stdout);
  859. X        LastCommand=command;
  860. X        if ( !(cstat & (ST_NORED | ST_COND))) { /* redirection not disabled */
  861. X            if (cin_name) {
  862. X                if (!(cin = extOpen(cin_name,MODE_OLDFILE))) {
  863. X                    ierror (NULL, 504);
  864. X                    err = 20;
  865. X                    cin_name = NULL;
  866. X                } else {
  867. X                    Myprocess->pr_CIS = DEVTAB(stdin) = cin;
  868. X                    ci = (struct FileHandle *)(cin<<2);
  869. X                    cin_buf = SAllocMem(202L, MEMF_PUBLIC);
  870. X                    oldbuf = ci->fh_Buf;
  871. X                    if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
  872. X                        ci->fh_Buf = (long)cin_buf>>2;
  873. X                }
  874. X            }
  875. X            if (cout_name) {
  876. X                if (cout_append && (cout =extOpen(cout_name,1005L))) {
  877. X                    Seek(cout, 0L, OFFSET_END );
  878. X                } else {
  879. X                    cout = extOpen(cout_name,MODE_NEWFILE);
  880. X                }
  881. X                if (cout == NULL) {
  882. X                    err = 20;
  883. X                    ierror (NULL, 504);
  884. X                    cout_name = NULL;
  885. X                    cout_append = 0;
  886. X                } else {
  887. X                    Myprocess->pr_COS = DEVTAB(stdout) = cout;
  888. X                }
  889. X            }
  890. X        }
  891. X
  892. X        if( Verbose&VERBOSE_ALIAS ) {
  893. X            if( Verbose&VERBOSE_HILITE ) fprintf(stderr,"%s",o_hilite);
  894. X            if( pend_alias )
  895. X                fprintf(stderr,"%-*s%s %s\n",alias_count,">",av[0],avline);
  896. X            else 
  897. X                fprintf(stderr,"%-*s%s\n",alias_count,">",avline);
  898. X            if( Verbose&VERBOSE_HILITE ) fprintf(stderr,"%s",o_lolite);
  899. X        }
  900. X
  901. X        if( pend_alias ) {
  902. X            char *scr;
  903. X            FRAME *subframe=NULL;
  904. X
  905. X            if( ccno==2 ) {                         /* has arguments */
  906. X                char *ptr=pend_alias, *val=avline;
  907. X                int clen;
  908. X
  909. X                clen=strlen(ptr)*2+20;
  910. X                newframe( &subframe, clen+DEFAULTFRAME );
  911. X                push_locals( (ROOT *)falloc( &subframe, sizeof(ROOT) ));
  912. X                do {                                       /* set all args    */
  913. X                    char *varname, *gap=NULL;
  914. X                    for( varname= ++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr);
  915. X                    if( *ptr=='%' && (gap=index(val,0xA0 )) ) *gap=0;
  916. X                    set_var( LEVEL_LOCAL, varname, val );
  917. X                    val= gap ? gap+1 : "";
  918. X                } while( *ptr=='%' );
  919. X                scr = falloc(&subframe,clen);
  920. X                preformat (ptr, scr);
  921. X            } else {
  922. X                char *scr2;
  923. X                int  clen=strlen(pend_alias)+strlen(avline)+20;
  924. X
  925. X                newframe( &subframe,3*clen+DEFAULTFRAME );
  926. X                push_locals( (ROOT *)falloc( &subframe, sizeof(ROOT) ));
  927. X                scr2= falloc( &subframe,clen );
  928. X                sprintf(scr2,"%s %s",pend_alias,avline);
  929. X                scr = falloc( &subframe, 2*clen );
  930. X                preformat( scr2,scr);
  931. X            }
  932. X            fcomm (scr,&subframe,pend_alias);
  933. X            pop_locals();
  934. X            deleteframe(subframe);
  935. X        } else {
  936. X            if (ac < Command[ccno].minargs + 1) {
  937. X                show_usage( NULL );
  938. X                err = 20;
  939. X                if (E_stack == 0 )
  940. X                    seterr(err);
  941. X            } else if (!err) {
  942. X                int (*func)(char*,int)=Command[ccno].func, i;
  943. X                get_opt( av, &ac, ccno );
  944. X                i=0;
  945. X                if( ccno>0 && ac==2 && !strcmp(av[1],"?") )
  946. X                    show_usage(avline);
  947. X                else 
  948. X                    i = (*func)(avline, Command[ccno].val); /*  do the call */ 
  949. X                if (i < 0)
  950. X                    i = 20;
  951. X                err = i;
  952. X                if (E_stack == 0 )
  953. X                    seterr(err);
  954. X                fflush(stderr);
  955. X            }
  956. X        }
  957. X        if (!(cstat & (ST_NORED | ST_COND))) {
  958. X            if (cin_name) {
  959. X                ci->fh_Buf = oldbuf;
  960. X                fflush(stdin);
  961. X                clearerr(stdin);
  962. X#ifdef AZTEC_C
  963. X                stdin->_bp=stdin->_bend;
  964. X#else
  965. X                stdin->_rcnt=stdin->_wcnt;
  966. X#endif
  967. X                extClose(cin);
  968. X                FreeMem(cin_buf, 202L);
  969. X            }
  970. X            if (cout_name) {
  971. X                fflush(stdout);
  972. X                clearerr(stdout);
  973. X#ifdef AZTEC_C
  974. X                stdout->_flags &= ~_IODIRTY;    /* because of nil: device */
  975. X#endif
  976. X                extClose(cout);
  977. X                cout_append = 0;
  978. X            }
  979. X        }
  980. X        Myprocess->pr_CIS = DEVTAB(stdin)  = oldcin;
  981. X        Myprocess->pr_COS = DEVTAB(stdout) = oldcout;
  982. X
  983. X        if (cin_ispipe && cin_name)
  984. X            DeleteFile(cin_name);
  985. X        if (cout_ispipe) {
  986. X            cin_name = cout_name;         /* ok to assign.. static name */
  987. X            cin_ispipe = 1;
  988. X        } else {
  989. X            cin_name = NULL;
  990. X        }
  991. X        cout_name = NULL;
  992. X        cout_ispipe = 0;
  993. X    }
  994. X
  995. Xdone0:
  996. X    {
  997. X        char *exc;
  998. X        if (err && E_stack==0) {
  999. X            exc = get_var(LEVEL_SET, v_except);
  1000. X            if (err >= ((exc)?atoi(exc):1)) {
  1001. X                if (exc) {
  1002. X                    ++H_stack, ++E_stack;
  1003. X                    a0tospace(exc);
  1004. X                    exec_command(exc);
  1005. X                    --E_stack, --H_stack;
  1006. X                } else {
  1007. X                    Exec_abortline = 1;
  1008. X                }
  1009. X            }
  1010. X            seterr(err);
  1011. X        }
  1012. X        if (elast != 0 && Exec_abortline == 0) {
  1013. X            memmove( str, nextstr, strlen(nextstr)+1 );
  1014. X            goto nextcommand;
  1015. X        }
  1016. X        Exec_abortline = 0;
  1017. X        if (cin_name)
  1018. X            DeleteFile(cin_name);
  1019. X    }
  1020. Xdone1:
  1021. X
  1022. X    av=oldav; ac=oldac; max_ac=oldmax;
  1023. X    --alias_count;
  1024. X    return err;                      /* TRUE = error occured    */
  1025. X}
  1026. X
  1027. X
  1028. Xstatic char *
  1029. Xexarg(char **ptr, char *elast)
  1030. X{
  1031. X    char *end, *start;
  1032. X
  1033. X    start = end = *ptr;
  1034. X    while ( *(signed char *)end>0 || *end && *end != 0x80 &&
  1035. X             *end != HOT_SEMI &&  *end != HOT_PIPE && *end != HOT_BLANK)
  1036. X        ++end;
  1037. X    *elast = *end;
  1038. X    *end = '\0';
  1039. X    *ptr = end + 1;
  1040. X    return start;
  1041. X}
  1042. X
  1043. X
  1044. Xstatic void
  1045. Xnewframe(FRAME **frameptr, int bytes)
  1046. X{
  1047. X    FRAME *new;
  1048. X
  1049. X    new=salloc( bytes + 4 + sizeof(FRAME) );
  1050. X    new->next= *frameptr;
  1051. X
  1052. X    new->bytesleft = bytes;
  1053. X    new->ptr       = new->mem;
  1054. X    *frameptr=new;
  1055. X}
  1056. X
  1057. Xstatic char *
  1058. Xfalloc( FRAME **frameptr, int bytes )
  1059. X{
  1060. X    char *mem,inc;
  1061. X
  1062. X    bytes+=2;                                    /* 2 extra bytes for do_run  */
  1063. X
  1064. X    if( (*frameptr)->bytesleft <= bytes )
  1065. X        newframe( frameptr, bytes+DEFAULTFRAME );
  1066. X
  1067. X    inc=4-((long)(*frameptr)->ptr&3);  /* 1 extra byte and longword alignment */
  1068. X    mem=(*frameptr)->ptr+inc;
  1069. X    (*frameptr)->bytesleft-=bytes+inc;
  1070. X    (*frameptr)->ptr      +=bytes+inc;
  1071. X    return mem;
  1072. X}
  1073. X
  1074. Xstatic char *
  1075. Xfrealloc( FRAME **frameptr, char *oldstring, int morebytes )
  1076. X{
  1077. X    char *mem=oldstring;
  1078. X
  1079. X    if( (*frameptr)->bytesleft <= morebytes ) {
  1080. X        int oldlen=(*frameptr)->ptr-oldstring;
  1081. X        newframe( frameptr, oldlen+morebytes+DEFAULTFRAME );
  1082. X        mem= (*frameptr)->ptr;
  1083. X        strcpy((*frameptr)->ptr,oldstring);
  1084. X        oldlen+=morebytes;
  1085. X        (*frameptr)->ptr      +=oldlen;
  1086. X        (*frameptr)->bytesleft-=oldlen;
  1087. X    }
  1088. X    (*frameptr)->bytesleft-=morebytes;
  1089. X    (*frameptr)->ptr      +=morebytes;
  1090. X    return mem;
  1091. X}
  1092. X
  1093. Xstatic void
  1094. Xfunalloc( FRAME **frameptr, int bytes )
  1095. X{
  1096. X    (*frameptr)->bytesleft+=bytes;
  1097. X    (*frameptr)->ptr      -=bytes;
  1098. X}
  1099. X
  1100. X
  1101. X
  1102. Xvoid
  1103. Xdeleteframe(FRAME *frame)
  1104. X{
  1105. X    FRAME *nxt;
  1106. X
  1107. X    for( ; frame; frame=nxt ) {
  1108. X        nxt=frame->next;
  1109. X        free(frame);
  1110. X    }
  1111. X}
  1112. X
  1113. X/*
  1114. X * Insert 'from' string in front of 'str' while deleting the
  1115. X * first entry in 'str'.  if freeok is set, then 'str' will be
  1116. X * free'd
  1117. X */
  1118. X
  1119. Xstatic char *
  1120. Xformat_insert_string(FRAME **frameptr, char *str, char *from)
  1121. X{
  1122. X    char *new, *strskip;
  1123. X    int len;
  1124. X
  1125. X    strskip=skipword( str );
  1126. X    len = strlen(from)*3+20;
  1127. X    new = falloc( frameptr, len);
  1128. X    preformat(from, new);
  1129. X    funalloc( frameptr, len -strlen(new)  - 2 );
  1130. X    frealloc( frameptr, new, strlen(strskip)+2);
  1131. X    strcat(new, strskip);
  1132. X    new[strlen(new)+1] = 0;
  1133. X    return new;
  1134. X}
  1135. X
  1136. Xstatic char *
  1137. Xskipword( char *strskip )
  1138. X{
  1139. X    for ( ; *(signed char *)strskip>0
  1140. X        || *strskip && *strskip != HOT_BLANK 
  1141. X        && *strskip != HOT_SEMI && *strskip != HOT_PIPE
  1142. X        && *strskip != 0x80; ++strskip);
  1143. X    return strskip;
  1144. X}
  1145. X
  1146. Xchar *
  1147. Xfind_internal( char *str )
  1148. X{
  1149. X    return Command[find_command(str)].name;
  1150. X}
  1151. X
  1152. Xstatic int
  1153. Xfind_command( char *str )
  1154. X{
  1155. X    int i, len = strlen(str);
  1156. X    struct COMMAND *com;
  1157. X    char c=*str;
  1158. X
  1159. X    for( com=Command, i=0; com->func; com++, i++ )
  1160. X        if ( c==*com->name && !strncmp(str, com->name, len))
  1161. X            if(o_abbrev || len==strlen(com->name))
  1162. X                return i;
  1163. X    return 0;
  1164. X}
  1165. X
  1166. Xint exec_fn_err;
  1167. X
  1168. Xextern struct FUNCTION {
  1169. X    short id, minargs, maxargs;
  1170. X    char *name;
  1171. X} Function[];
  1172. X
  1173. X
  1174. Xchar *gotfunc( int i, char **fav, int fac );
  1175. X
  1176. Xchar *
  1177. Xexec_function( char *str, char **fav, int fac)
  1178. X{
  1179. X    int len=strlen(str)-1, i;
  1180. X
  1181. X    exec_fn_err=0;
  1182. X    for (i = 0; Command[i].func; ++i)
  1183. X        if ( Command[i].stat&ST_FUNC && !strncmp(str,Command[i].name,len)) {
  1184. X            if( fac<Command[i].minargs ) {
  1185. X                exec_fn_err=20;
  1186. X                return NULL;
  1187. X            } else {
  1188. X                int (*func)( void )=Command[i].func;
  1189. X                char **oldav=av;
  1190. X                int  oldac=ac;
  1191. X                av=fav-1, ac=fac+1;
  1192. X                exec_fn_err=(*func)();
  1193. X                av=oldav, ac=oldac;
  1194. X                return get_var( LEVEL_SET, fav[0] );
  1195. X            }
  1196. X        }
  1197. X    for (i = 0; Function[i].id; ++i)
  1198. X        if ( len==strlen(Function[i].name)&&!strncmp(str,Function[i].name,len))
  1199. X            return gotfunc( i,fav,fac );
  1200. X
  1201. X    exec_fn_err=-1;
  1202. X    return NULL;
  1203. X}
  1204. X
  1205. Xint
  1206. Xechofunc(void)
  1207. X{
  1208. X    int  i;
  1209. X    char *str;
  1210. X
  1211. X    if( !strlen(av[0]) ) return -1;
  1212. X    exec_fn_err=0;
  1213. X    for (i = 0; Function[i].id; ++i)
  1214. X        if ( !strcmp(av[0],Function[i].name)) {
  1215. X            if(str=gotfunc( i,av,ac ))
  1216. X                printf("%s\n",str);
  1217. X            return exec_fn_err;
  1218. X        }
  1219. X    return -1;
  1220. X}
  1221. X
  1222. X
  1223. Xchar *
  1224. Xgotfunc( int i, char **fav, int fac )
  1225. X{
  1226. X    fac--; fav++;
  1227. X    if( fac<Function[i].minargs ) {
  1228. X        fprintf( stderr, "Not enough arguments for @%s\n",
  1229. X                          Function[i].name );
  1230. X        exec_fn_err=20;
  1231. X        return NULL;
  1232. X    } else if( fac>Function[i].maxargs ) {
  1233. X        if( ac > Function[i].maxargs )
  1234. X            fprintf( stderr, "Too many arguments for @%s\n",
  1235. X                              Function[i].name );
  1236. X        exec_fn_err=20;
  1237. X        return NULL;
  1238. X    } else {
  1239. X        exec_fn_err=dofunc( Function[i].id, fav, fac);
  1240. X        return get_var( LEVEL_SET, v_value );
  1241. X    }
  1242. X    return NULL;
  1243. X}
  1244. X
  1245. X
  1246. X
  1247. Xdo_help()
  1248. X{
  1249. X    struct COMMAND *com;
  1250. X    int i=0;
  1251. X
  1252. X    for (com = &Command[3]; com->func; ++com) {
  1253. X        printf ("%-12s", com->name);
  1254. X        if (++i % 6 == 0) printf("\n");
  1255. X    }
  1256. X    printf("\n\nUse   man <command>   for more information\n");
  1257. X    return 0;
  1258. X}
  1259. X
  1260. Xdo_nothing()
  1261. X{
  1262. X    return 0;
  1263. X}
  1264. X
  1265. Xstatic char *
  1266. Xpush_cpy(FRAME **frameptr, char *s)
  1267. X{
  1268. X    return strcpy(falloc(frameptr,strlen(s)+1), s);
  1269. X}
  1270. X
  1271. Xvoid
  1272. Xexec_every(void)
  1273. X{
  1274. X    char *str = get_var(LEVEL_SET, v_every);
  1275. X
  1276. X    if (str) {
  1277. X        ++H_stack, ++E_stack;
  1278. X        a0tospace( str );
  1279. X        exec_command(str);
  1280. X        --E_stack, --H_stack;
  1281. X    }
  1282. X}
  1283. X
  1284. Xchar *
  1285. Xa0tospace( str )
  1286. X    char *str;
  1287. X{
  1288. X    char *get=str, *put=str;
  1289. X
  1290. X    while( *get )
  1291. X        if( *get==0xA0 )
  1292. X            *put++=' ', get++;
  1293. X        else 
  1294. X            *put++=*get++;
  1295. X    return str;
  1296. X}
  1297. X
  1298. Xvoid
  1299. Xshow_usage( str )
  1300. X    char *str;
  1301. X{
  1302. X    int ccno, first=0, err=0;
  1303. X    char *get, *put, buf[300];
  1304. X
  1305. X    if( !str )
  1306. X        str=LastCommand, err=1;
  1307. X    for( put=str; *put && (*put&127)!=32; put++ ) ;
  1308. X    *put=0;
  1309. X
  1310. X    put=buf;
  1311. X    ccno = find_command (str);
  1312. X    if( get= Command[ccno].usage ) {
  1313. X        do {
  1314. X            put+=sprintf(put, first++?"       %s ":"Usage: %s ",
  1315. X                         Command[ccno].name );
  1316. X            if( *get=='-' ) {
  1317. X                *put++='['; *put++='-';
  1318. X                get++;
  1319. X                while( *get && *get!=' ' && *get!=',' )
  1320. X                    *put++=*get++;
  1321. X                *put++=']';
  1322. X            }
  1323. X            while( *get && *get!=','  )
  1324. X                *put++=*get++;
  1325. X            *put++='\n';
  1326. X        } while( *get++ );
  1327. X        *put=0;
  1328. X        fprintf( err ? stderr : stdout, "%s", buf );
  1329. X    }
  1330. X}
  1331. X
  1332. Xint
  1333. Xexecute( char *str )
  1334. X{
  1335. X    ULONG toptions=options;
  1336. X    BPTR  toldcin=OldCin;
  1337. X    int   ret, oldac=ac, oldmax=max_ac;
  1338. X    char  **oldav=av;
  1339. X
  1340. X    if( !str ) return -1;
  1341. X
  1342. X    ++H_stack;
  1343. X    ret=exec_command(str);
  1344. X    --H_stack;
  1345. X
  1346. X    av=oldav; max_ac=oldmax; ac=oldac;
  1347. X    options=toptions; OldCin=toldcin;
  1348. X
  1349. X    return ret;
  1350. X}
  1351. X
  1352. Xdo_exec( char *str )
  1353. X{
  1354. X    return execute( next_word( str ) );
  1355. X}
  1356. X
  1357. Xint
  1358. Xinteractive( void )
  1359. X{
  1360. X    return IsInteractive(Output());
  1361. X}
  1362. X
  1363. Xstatic int
  1364. Xcheckav( FRAME **frameptr, int n )
  1365. X{
  1366. X    char **tmp;
  1367. X    int newac;
  1368. X
  1369. X    if( ac+n+10>=max_ac ) {
  1370. X        newac=max_ac+n+40;
  1371. X        tmp=(char **)falloc(frameptr,newac*sizeof(char *));
  1372. X        memcpy(tmp,av,max_ac*sizeof(char *));
  1373. X        av=tmp; max_ac=newac;
  1374. X    }
  1375. X    return 0;
  1376. X}
  1377. X
  1378. X/*    Parse the options specified in sw[]
  1379. X    Setting a bit in global variable options
  1380. X    for each one found
  1381. X*/
  1382. X
  1383. Xstatic void
  1384. Xget_opt( char **av, int *ac, int ccno )
  1385. X{
  1386. X    char **get=av+1,**put=av+1, *c, *s;
  1387. X    int i=1, l, usage=0, nac;
  1388. X    long oldopts;
  1389. X
  1390. X    options=0;
  1391. X    if( !ccno )
  1392. X        return;
  1393. X
  1394. X    for( ; i<*ac && *av[i]=='-'; i++, get++ ) {
  1395. X        if( !*(c=*get+1) )
  1396. X            goto stop;
  1397. X        oldopts=options;
  1398. X        for ( ; *c ; c++) {
  1399. X            if( *c<'a' || *c>'z' ) 
  1400. X                { options=oldopts; goto stop; }
  1401. X            for( l=0, s=Command[ccno].options; *s && *s != *c; ++s )
  1402. X                ++l;
  1403. X            if ( *s )
  1404. X                options |= (1 << l);
  1405. X            else if( !usage ) {
  1406. X                usage=1;
  1407. X                show_usage(NULL);
  1408. X            }
  1409. X        }
  1410. X    }
  1411. Xstop:
  1412. X    for( nac=1; i<*ac; i++ )
  1413. X        *put++=*get++, nac++;
  1414. X    *put=NULL;
  1415. X    *ac=nac;
  1416. X}
  1417. X
  1418. X#if 0
  1419. XUSHORT Options[160];
  1420. X
  1421. Xint
  1422. Xdo_options()
  1423. X{
  1424. X    for( i=1; i<ac; i+=2 ) {
  1425. X        if( ac-i<=1 )
  1426. X            { ierror( av[i], 500 ); return 20; }
  1427. X        if( *av[i+1]!='-' )
  1428. X            { ierror( av[i+1], 500 ); return 20; }
  1429. X        options=0;
  1430. X        parseopts( av[i+1]+1 );
  1431. X    }
  1432. X}
  1433. X#endif
  1434. X
  1435. Xextern char *MyMem;
  1436. Xstatic char Pipe[2][32];
  1437. X
  1438. Xchar *
  1439. Xtempname( int which )
  1440. X{
  1441. X    sprintf(Pipe[which],"%spipe%c%d_%lx",o_pipe,'A'+which,alias_count,MyMem);
  1442. X    return Pipe[which];
  1443. X}
  1444. X
  1445. X#define ISSPACE(c) ((c)==' ' || (c)==9 || (c)==0xA0)
  1446. X
  1447. Xstatic int
  1448. Xhasspace( char *s )
  1449. X{
  1450. X    if( !*s )
  1451. X        return 1;
  1452. X    for ( ; *s; s++)
  1453. X        if (ISSPACE(*s)) return 1;
  1454. X    return 0;
  1455. X}
  1456. X
  1457. Xchar *
  1458. Xcompile_avf(FRAME **framep,char **av, int start, int end, char delim, int quote)
  1459. X{
  1460. X    char *cstr, *p;
  1461. X    int len, i;
  1462. X
  1463. X    len = 3;
  1464. X    for (i = start; i < end; ++i) len += strlen(av[i]) + 3;
  1465. X    if( framep )
  1466. X        p = cstr = falloc(framep,len);
  1467. X    else 
  1468. X        p = cstr = salloc(len);
  1469. X    *cstr = '\0';
  1470. X    for (i = start; i < end; ++i) {
  1471. X        if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]);
  1472. X        if (quote && hasspace(av[i]))
  1473. X            p += sprintf(p, "\"%s\"", av[i]);
  1474. X        else
  1475. X            p += sprintf(p, "%s",     av[i]);
  1476. X        if (i+1 < end) *p++=delim;
  1477. X    }
  1478. X    *p='\0';
  1479. X    return cstr;
  1480. X}
  1481. X
  1482. Xchar *
  1483. Xcompile_av(char **av, int start, int end, char delim, int quote)
  1484. X{
  1485. X    return compile_avf(NULL,av, start, end, delim, quote);
  1486. X}
  1487. X
  1488. Xstatic int
  1489. Xmyfgets( char *buf, FILE *in )
  1490. X{
  1491. X    int l;
  1492. X    char *ret;
  1493. X    if( ret=fgets(buf,253,in) ) {
  1494. X        l=strlen(buf);
  1495. X        if( buf[l-1]=='\n' )
  1496. X            buf[l-1]=0;
  1497. X    }
  1498. X    return ret!=NULL && !dobreak();
  1499. X}
  1500. END_OF_FILE
  1501. if test 37168 -ne `wc -c <'execom.c'`; then
  1502.     echo shar: \"'execom.c'\" unpacked with wrong size!
  1503. fi
  1504. # end of 'execom.c'
  1505. fi
  1506. echo shar: End of archive 6 \(of 6\).
  1507. cp /dev/null ark6isdone
  1508. MISSING=""
  1509. for I in 1 2 3 4 5 6 ; do
  1510.     if test ! -f ark${I}isdone ; then
  1511.     MISSING="${MISSING} ${I}"
  1512.     fi
  1513. done
  1514. if test "${MISSING}" = "" ; then
  1515.     echo You have unpacked all 6 archives.
  1516.     rm -f ark[1-9]isdone
  1517. else
  1518.     echo You still need to unpack the following archives:
  1519.     echo "        " ${MISSING}
  1520. fi
  1521. ##  End of shell archive.
  1522. exit 0
  1523. -- 
  1524. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  1525. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  1526. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  1527.